﻿using System.Security.Cryptography.X509Certificates;
using CommunityToolkit.Mvvm.Messaging;
using Dark_Core_Server.Models.Article;
using Dark_Core_Server.Models.Message;
using Dark_Core_Server.Models.Universal;
using Dark_Core_Server.Models.User;
using DarkSKL_Core.ArgModules;
using DarkSKL_Core.ConfigModules;
using DarkSKL_Core.MongoDBModules.Helper;
using DarkSKL_Core.MongoDBModules.Models;
using MongoDB.Bson;
using MongoDB.Driver;
using Serilog;

namespace Dark_Core_Server.Service
{
    /// <summary>
    /// 消息服务
    /// </summary>
    public class MessageService
    {
        /// <summary>
        /// 消息集合
        /// </summary>
        public IMongoCollection<MsgDocument> MsgCollection;
        public MessageService()
        {
            DatabaseConfig config = new DatabaseConfig()
            {
                DatabaseName = EnvironmentConfigController.ConfigController.GetConfig<string>("DB:MESSAGE_DB_NAME"),
                User = EnvironmentConfigController.ConfigController.GetConfig<string>("DB:USER"),
                Password = EnvironmentConfigController.ConfigController.GetConfig<string>("DB:PASS"),
                Host = EnvironmentConfigController.ConfigController.GetConfig<string>("DB:HOST"),
                Port = EnvironmentConfigController.ConfigController.GetConfig<int>("DB:PORT"),
                Args = EnvironmentConfigController.ConfigController.GetConfig<string>("DB:ARGS")
            };
            MsgCollection = MongodbBuilder.CreateCollection<MsgDocument>(config,
                EnvironmentConfigController.ConfigController.GetConfig<string>("DB:MESSAGE_DB_COLLECTION") ?? "basicUnit");


            WeakReferenceMessenger.Default.Register<UserDocument, string>(this, "UserDeleted",
                 UserDeletedHandler);
        }



        #region Create创建
        /// <summary>
        /// 创建消息
        /// </summary>
        /// <param name="publisherId">发布者ID</param>
        /// <param name="record">记录</param>
        /// <returns></returns>
        public async Task<ResponseMsg<bool>> CreateMsg(ObjectId publisherId,SimpleMsgRecord record)
        {
            try
            {
                MsgDocument document = record.CreateDocument(publisherId);
                await MsgCollection.InsertOneAsync(document);
                return true.CreateResponseMsg("创建成功", UniversalState.Success);
            }
            catch (Exception e)
            {
                Log.Error($"MessageService.CreateMsg Exception:{e.Message}");
                return false.CreateResponseMsg($"MessageService.CreateMsg Exception:{e.Message}", UniversalState.Error);
            }
        }

        #endregion


        #region Delete删除
        /// <summary>
        /// 删除消息
        /// </summary>
        /// <param name="publisherId">发布者ID</param>
        /// <param name="msgId">消息ID</param>
        /// <returns></returns>
        public async Task<ResponseMsg<bool>> DeleteMsg(ObjectId publisherId, ObjectId msgId)
        {
            try
            {
                await MsgCollection.DeleteOneAsync(x => x.PublisherId == msgId && x.id == msgId);
                return true.CreateResponseMsg("删除成功", UniversalState.Success);
            }
            catch (Exception e)
            {
                Log.Error($"MessageService.CreateMsg Exception:{e.Message}");
                return false.CreateResponseMsg($"MessageService.DeleteMsg Exception:{e.Message}", UniversalState.Error);
            }
        }

        /// <summary>
        /// 清除消息
        /// </summary>
        /// <param name="publisherId">发布者ID</param>
        /// <returns></returns>
        public async Task<ResponseMsg<bool>> ClearMsg(ObjectId publisherId)
        {
            try
            {
                await MsgCollection.DeleteManyAsync(x => x.PublisherId == publisherId);
                return true.CreateResponseMsg("清除成功", UniversalState.Success);
            }
            catch (Exception e)
            {
                Log.Error($"MessageService.ClearMsg Exception:{e.Message}");
                return false.CreateResponseMsg($"MessageService.ClearMsg Exception:{e.Message}", UniversalState.Error);
            }
        }

        private async void UserDeletedHandler(object recipient, UserDocument args)
        {
            await this.ClearMsg(args.id);
        }

        #endregion


        #region Query查询消息
        /// <summary>
        /// 查询消息异步
        /// </summary>
        /// <param name="mode">查询模式</param>
        /// <param name="userDocument">当前用户信息</param>
        /// <param name="args">查询参数</param>
        /// <param name="pageIndex">分页序号</param>
        /// <param name="pageSize">分页大小</param>
        /// <returns>回应消息</returns>
        public async Task<ResponseMsg<DataArrResponse<MsgDocument> >> QueryMsg(MsgQueryMode mode, UserDocument userDocument, string args, int pageIndex = 0, int pageSize = 999)
        {
            try
            {
                var findOption = new FindOptions<MsgDocument>()
                {
                    Skip = pageIndex * pageSize,
                    Limit = pageSize
                };

                var findFilter = mode switch
                {
                    MsgQueryMode.All => Builders<MsgDocument>.Filter.Lte(x => x.RecipientLevel, userDocument.Level),
                    MsgQueryMode.Title => Builders<MsgDocument>.Filter.And(
                        Builders<MsgDocument>.Filter.Lte(x => x.RecipientLevel, userDocument.Level),
                        Builders<MsgDocument>.Filter.Regex(x => x.Title, new BsonRegularExpression(args, "i"))
                    ),
                    MsgQueryMode.Tag => Builders<MsgDocument>.Filter.And(
                        Builders<MsgDocument>.Filter.Lte(x => x.RecipientLevel, userDocument.Level),
                        Builders<MsgDocument>.Filter.Eq(x => x.Tag, args)
                    ),
                    _ => throw new Exception("Unknown Query mode")
                };
                var findCount = await MsgCollection.CountDocumentsAsync(findFilter);
                var findResult = await MsgCollection.FindAsync(findFilter, findOption);
                var result = await findResult.ToListAsync();
                return result.ToDataArrResponse(findCount).CreateResponseMsg("查询成功", UniversalState.Success);
            }
            catch (Exception e)
            {
                Log.Error($"MessageService.QueryMsg Exception:{e.Message}");
                return new List<MsgDocument>().ToDataArrResponse(0).CreateResponseMsg($"MessageService.QueryMsg Exception:{e.Message}", UniversalState.Error);
            }
        }


        #endregion

    }
}
